package com.blog.wu.myblog.config;

import com.blog.wu.myblog.base.BaseService;
import com.blog.wu.myblog.entity.UserInfo;
import com.blog.wu.myblog.util.WebPropertiesConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author wuyanshen
 * @Date 2018-10-17 下午1:30
 * @Discription 统计在线人数
 */
@WebListener
public class WebSessionListener extends BaseService implements HttpSessionListener, HttpSessionAttributeListener {


    /**
     * session创建时被调用
     */
    @Override
    public void sessionCreated(HttpSessionEvent sessionEvent) {
        logger.info("session创建...");
    }

    /**
     * session销毁时被调用
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent sessionEvent) {
        logger.info("session销毁...");
        // 获取即将被销毁的session
        HttpSession session = sessionEvent.getSession();
        // 在map中根据key移除
        ApplicationConstants.SESSION_MAP.remove(session.getId());
    }

    /**
     * 添加session属性时被调用
     */
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {

        // 判断是否添加的用户登录信息session
        if (event.getName().equals(ApplicationConstants.LOGIN_SESSION_NAME)) {

            // 是否在其他机器登录处理
            isLoginInOtherPlace(event);

            // 获取创建的session
            HttpSession session = event.getSession();

            // 添加到map
            ApplicationConstants.SESSION_MAP.put(session.getId(), session);
            // 访问总人数++
            ApplicationConstants.TOTAL_HISTORY_COUNT++;
            // 如果map总数大于最高同时在线人数则更新最高在线人数及时间
            if (ApplicationConstants.MAX_ONLINE_COUNT < ApplicationConstants.SESSION_MAP.size()) {
                ApplicationConstants.MAX_ONLINE_COUNT = ApplicationConstants.SESSION_MAP.size();
                ApplicationConstants.MAX_ONLINE_COUNT_DATE = new Date();
            }

            // 当前登录用户数++
            ApplicationConstants.CURRENT_LOGIN_COUNT++;


            showCurrentCount("添加session后");

            logger.info("TOTAL_HISTORY_COUNT = {}",ApplicationConstants.TOTAL_HISTORY_COUNT);
            logger.info("MAX_ONLINE_COUNT = {}",ApplicationConstants.MAX_ONLINE_COUNT);
            logger.info("MAX_ONLINE_COUNT_DATE = {}",ApplicationConstants.MAX_ONLINE_COUNT_DATE);
            logger.info("CURRENT_LOGIN_COUNT = {}",ApplicationConstants.CURRENT_LOGIN_COUNT);
        }


    }

    /**
     * 展示当前在线人数
     *
     * @param
     * @return void
     * @Date 2018/10/18 下午3:33
     * @Author wuyanshen
     */
    private void showCurrentCount(String flag) {
        String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        logger.info("=================== " + flag + " =====================");
        logger.info("==      当前【" + currentTime + "】在线人数：{}人     ==", ApplicationConstants.CURRENT_LOGIN_COUNT);
        logger.info("======================================================");
    }

    /**
     * 移除session属性时被调用
     */
    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        // 判断是否移除的用户登录信息session
        if (event.getName().equals(ApplicationConstants.LOGIN_SESSION_NAME)) {
            // 当前登录用户数--
            ApplicationConstants.CURRENT_LOGIN_COUNT--;
            if (ApplicationConstants.CURRENT_LOGIN_COUNT < 0) {
                ApplicationConstants.CURRENT_LOGIN_COUNT = 0;
            }

            // 是否在其他机器登录处理 (这里不能再检测了，否则移除的session的even会再传入，再判断就会把当前session也清除，导致当前登录和其他登录都失效！)
//            isLoginInOtherPlace(event);

            showCurrentCount("移除session后");
        }
    }

    /**
     * 修改session属性时被调用
     */
    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {

        // 判断是否修改的用户登录信息session
        if (event.getName().equals(ApplicationConstants.LOGIN_SESSION_NAME)) {
            // 是否在其他机器登录处理
            isLoginInOtherPlace(event);
        }
    }

    /**
     * 是否在其他机器登录处理
     *
     * @param event
     */
    private void isLoginInOtherPlace(HttpSessionBindingEvent event) {
        if (!WebPropertiesConfig.sameAccountMultiLogin) {
            // 获取添加的session
            HttpSession session = event.getSession();
            // 遍历查找此用户是否登录
            for (HttpSession oldSession : ApplicationConstants.SESSION_MAP.values()) {
                // 如果已经在其他机器登录则使其失效
                if (event.getValue().equals(oldSession.getAttribute(ApplicationConstants.LOGIN_SESSION_NAME))
                        && session.getId() != oldSession.getId()) {
                    // 使session失效
                    oldSession.invalidate();//将其他地方登陆的账号踢掉
                    break;
                }
            }

        }
    }
}
